package com.yanqu.road.logic.xlogic.rank.channel;

import com.yanqu.road.entity.rank.xrank.XChannelRankPart;
import com.yanqu.road.logic.bussiness.rank.XRankBussiness;
import com.yanqu.road.logic.pb.XRankPb;
import com.yanqu.road.logic.sort.XChannelRankSort;
import com.yanqu.road.logic.xlogic.base.BaseXMap;
import com.yanqu.road.logic.xlogic.base.IChannelActivityMaxRank;
import com.yanqu.road.logic.xlogic.base.IChannelRankPartNum;
import com.yanqu.road.pb.cross3.activity.XRankProto;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 区域榜
 */
public class XChannelRankMap extends BaseXMap {

    private IChannelActivityMaxRank maxRank;
    private IChannelRankPartNum partNum;

    public XChannelRankMap(String dbName, String tableName, IChannelActivityMaxRank maxRank, IChannelRankPartNum partNum) {
        super(dbName, tableName);
        this.maxRank = maxRank;
        this.partNum = partNum;
    }

    /**
     * 榜单    （活动ID，conditionType，榜单）
     */
    private final Map<Integer, Map<Integer, XChannelRankListModel>> channelRankMap = new ConcurrentHashMap<>();

    /**
     * 拿榜单
     */
    public XChannelRankListModel getChannelRankListModel(int activityId, int conditionType) {

        if (!channelRankMap.containsKey(activityId)) {
            synchronized (channelRankMap) {
                if (!channelRankMap.containsKey(activityId)) {
                    loadChannelRankListModel(activityId); // 读数据库
                }
            }
        }

        if (!channelRankMap.get(activityId).containsKey(conditionType)) {
            synchronized (channelRankMap) {
                if (!channelRankMap.get(activityId).containsKey(conditionType)) {
                    channelRankMap.get(activityId).put(conditionType,
                            new XChannelRankListModel(dbName, tableName, activityId, conditionType, maxRank.getChannelActivityMaxRank(activityId, conditionType), new XChannelRankSort(), partNum.getChannelRankPartNum(activityId)));
                }
            }
        }

        return channelRankMap.get(activityId).get(conditionType);
    }

    /**
     * 榜单刷新
     */
    public void rankChange(int activityId, int conditionType, int channelId) {
        XChannelRankListModel channelRankListModel = getChannelRankListModel(activityId, conditionType);
        channelRankListModel.rankChange(channelId);
    }

    /**
     * 贡献值变更
     */
    public void partValueChange(XChannelRankPart part, boolean needSync, boolean rankChange) {
        getChannelRankListModel(part.getActivityId(), part.getConditionType()).partValueChange(part, needSync, rankChange);
    }

    /**
     * 获取有变化的贡献值 并重置标志
     */
    public List<XRankProto.XChannelRankPartListMsg.Builder> getSyncPartCacheAndClear() {
        List<XRankProto.XChannelRankPartListMsg.Builder> list = new ArrayList<>();
        for (Map<Integer, XChannelRankListModel> modelMap : getChannelRankMap().values()) {

            for (XChannelRankListModel model : modelMap.values()) {
                List<XChannelRankPart> partList = model.getSyncPartCacheAndClear();
                if (partList.isEmpty()) {
                    continue;
                }

                XRankProto.XChannelRankPartListMsg.Builder partListMsg = XRankPb.parseXChannelRankPartListMsg(model.getActivityId(), model.getConditionType(), partList);
                list.add(partListMsg);
            }
        }
        return list;
    }

    /**
     * 读库获取数据
     */
    private void loadChannelRankListModel(int activityId) {
        List<XChannelRankPart> partList = XRankBussiness.getXChannelRankPartList(dbName, tableName, activityId);
        // 分类
        Map<Integer, List<XChannelRankPart>> partMap = new ConcurrentHashMap<>();
        for (XChannelRankPart part : partList) {
            partMap.putIfAbsent(part.getConditionType(), new ArrayList<>());
            partMap.get(part.getConditionType()).add(part);
        }
        // 初始化
        Map<Integer, XChannelRankListModel> map = new ConcurrentHashMap<>();
        for (Map.Entry<Integer, List<XChannelRankPart>> entry : partMap.entrySet()) {
            int conditionType = entry.getKey();
            List<XChannelRankPart> rankPartList = entry.getValue();
            XChannelRankListModel model = new XChannelRankListModel(dbName, tableName, activityId, conditionType, maxRank.getChannelActivityMaxRank(activityId, conditionType), new XChannelRankSort(), partNum.getChannelRankPartNum(activityId));
            model.initByPartMap(rankPartList);
            map.put(conditionType, model);
        }
        // 替换
        channelRankMap.put(activityId, map);
    }

    /**
     * 获取全部榜单
     */
    public Map<Integer, Map<Integer, XChannelRankListModel>> getChannelRankMap() {
        return channelRankMap;
    }

    @Override
    public void save() {
        for (Map<Integer, XChannelRankListModel> modelMap : channelRankMap.values()) {
            for (XChannelRankListModel model : modelMap.values()) {
                model.save();
            }
        }
    }

    @Override
    public void loadDb(Object param) {

    }
}
